const socket = require('./socket');
const {
  getObjLength
} = require('../../lib/util')

// 每个玩家链接
class Client {
  constructor() {
    this.players = {};
  }

  init() {
    socket.io.on('connection', sock => {
      this.add(sock);
      this.bindEvent(sock);

      sock.on('leave', () => {
        this.leave(sock);
      })
      sock.on('disconnect', () => {
        this.leave(sock);
      })
    })
  }

  addFrame(frame){
    this.frame = frame;
  }

  bindEvent(sock){
    sock.on('getGameLog', () => {
      sock.emit('getGameLog', this.frame.actions);
    })
  }

  add(sock) {
    sock.on('add', data => {
      this.frame.actions.push({
        action: 'addPlayer',
        data
      });
      let player = new Player(sock, data, this);
      this.players[sock.id] = player;
      player.add();
      player.listen();
      sock.emit('add');
    })
  }

  leave(sock) {
    if (!this.players[sock.id]) return;
    this.frame.actions.push({
      action: 'leavePlayer',
      id: sock.id
    });
    socket.sendAll({
      action: 'leavePlayer',
      id: sock.id
    })
    this.players[sock.id].leave();
    delete this.players[sock.id];

    socket.sendAll({
      action: 'info',
      playerNum: getObjLength(this.players),
    });
  }
}

class Player {
  constructor(sock, data, client) {
    this.id = sock.id;
    this.sock = sock;
    this.client = client;
    this.setKey = [];

    Object.keys(data).forEach(key => {
      this[key] = data[key] || false;
      this.setKey.indexOf(key) < 0 &&
        this.setKey.push(key);
    });

    this.operation = [];
  }

  listen() {
    this.sock.on('action', data => {
      this.operation.push(data.action);
    })
    this.sock.on('uploadData', data => {
      Object.keys(data).forEach(key => {
        this.setKey.indexOf(key) < 0 &&
          this.setKey.push(key);
        this[key] = data[key];
      })
    })
  }

  add() {
    let allPlayerData = [];
    Object.keys(this.client.players).forEach(item => {
      item = this.client.players[item];
      let data = {};
      data.id = item.id;
      data.username = item.username;
      item.setKey.map(key => {
        data[key] = item[key]
      })
      allPlayerData.push(data);
    });
    socket.sendAll({
      action: 'info',
      playerNum: getObjLength(this.client.players),
    });
    socket.sendAll({
      action: 'addPlayer',
      data: (allPlayerData.filter(i => i.id == this.id))[0]
    })
    socket.sendMe(this.sock, {
      action: 'basicPlayer',
      allPlayerData
    })
  }

  leave() {
    socket.sendAll({
      action: 'info',
      playerNum: getObjLength(this.client.players),
      leaveUser: this.username,
      id: this.sock.id
    });
  }
}

module.exports = Client;